package com.sinosoft.sinopay.apiservice.cacpspay.service;

import cacps.UploadFileService;
import com.caucho.hessian.client.HessianProxyFactory;
import com.sinosoft.sinocloud.platform.base.SinoBaseCheckException;
import com.sinosoft.sinocloud.platform.base.SinoBaseService;
import com.sinosoft.sinocloud.platform.common.util.XStreamComponent;
import com.sinosoft.sinopay.api.pay.dto.CacpsPayDTO;

import com.sinosoft.sinopay.api.pay.dto.CacpsPayRetuenDTO;
import com.sinosoft.sinopay.api.pay.service.CacpsPayApiService;
import com.sinosoft.sinopay.apiservice.cacpspay.dto.*;
import com.sinosoft.sinopay.apiservice.cacpspay.util.PropertiesUtils;
import com.snca.pfx.env.dec.SncaEnvDec;
import com.snca.swxa.env.enc.SncaEnvEnc;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PostMethod;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.IOException;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.util.Properties;

/**
 * 【 西安直连实时交易接口实现 】
 *
 * @author chenzhiheng
 * @version V1.0
 * @date 16/12/26
 */
@Service("CacpsPay")
public class CacpsPayServiceImpl extends SinoBaseService implements CacpsPayApiService {

    @Autowired
    private  UploadFileService uploadFileService ;

    private String pfxPass  ;

    @Override
    public CacpsPayRetuenDTO payRequest(CacpsPayDTO cacpsPayDTO)
            throws SinoBaseCheckException, Exception {
        //定义返回信息
        CacpsPayRetuenDTO cacpsPayRetuen = new CacpsPayRetuenDTO();
        try {
            XdirectpayReqXml reqXml = new XdirectpayReqXml();
            XdirectpayReqInfo xdirectpayReqInfo = new XdirectpayReqInfo();

            //读取配置文件
            String tPath = "/config/cacpsConfig.properties";
            Properties properties = PropertiesUtils.readProperties(tPath);
            pfxPass = properties.getProperty("CACPS_CERTIFICATE_PASSWORD");
            xdirectpayReqInfo.setCorpNo(properties.getProperty("CACPS_CORP_NO"));
            xdirectpayReqInfo.setFeeNo(properties.getProperty("CACPS_FEE_NO"));
            xdirectpayReqInfo.setTranCode(properties.getProperty("CACPS_TRANCODE_S"));
            xdirectpayReqInfo.setVersion("V1.00");
            reqXml.setHead(xdirectpayReqInfo);

            XdirectpayReqBody xdirectpayReqBody = new XdirectpayReqBody();
            xdirectpayReqBody.setCbtrActName(cacpsPayDTO.getCdtrActName());
            xdirectpayReqBody.setCdtrActId(cacpsPayDTO.getCdtrActId());
            xdirectpayReqBody.setCustEmail("");
            xdirectpayReqBody.setCustName("");
            xdirectpayReqBody.setDbtrActName(cacpsPayDTO.getDbtrActName());
            xdirectpayReqBody.setDbtrBankCity(cacpsPayDTO.getDbtrBankCity());
            xdirectpayReqBody.setDbtrActId(cacpsPayDTO.getDbtrActId());
            xdirectpayReqBody.setUse(cacpsPayDTO.getUse());
            xdirectpayReqBody.setSerialNum(properties.getProperty("CACPS_USER_NO"));
            xdirectpayReqBody.setRemark("");
            xdirectpayReqBody.setProductInfo("");
            xdirectpayReqBody.setPayAmt(cacpsPayDTO.getPayAmt());
            xdirectpayReqBody.setDbtrProtocol("22222");
            xdirectpayReqBody.setDbtrPhone(cacpsPayDTO.getDbtrPhone());
            xdirectpayReqBody.setDbtrCertType(cacpsPayDTO.getDbtrCertType());
            xdirectpayReqBody.setDbtrCertNo(cacpsPayDTO.getDbtrCertNo());
            xdirectpayReqBody.setDbtrCardType("02");
            xdirectpayReqBody.setDbtrCardExpired(cacpsPayDTO.getDbtrCardExpired());
            xdirectpayReqBody.setDbtrCardCVN2(cacpsPayDTO.getDbtrCardCVN2());
            xdirectpayReqBody.setDbtrBankType(cacpsPayDTO.getDbtrBankType());
            xdirectpayReqBody.setDbtrBankProvince(cacpsPayDTO.getDbtrBankProvince());
            xdirectpayReqBody.setDbtrBankName(cacpsPayDTO.getDbtrBankName());
            xdirectpayReqBody.setDbtrBankId(cacpsPayDTO.getDbtrBankId());

            reqXml.setIn(xdirectpayReqBody);
            XStreamComponent xstream = new XStreamComponent();
            xstream.processAnnotations(new Class[]{XdirectpayReqInfo.class, XdirectpayReqBody.class, XdirectpayReqXml.class, XdirectpayResXml.class,
                    XdirectpayResInfo.class, XdirectpayResBody.class});
            String requestXml = xstream.toXML(reqXml).replace("__", "_");
            //数据签名
            String signData = this.signMsg(requestXml).replace("__", "_");
            //请求西安直连支付
            String strResp = PayRequest(signData);

            //解析返回报文
            XdirectpayResXml response = (XdirectpayResXml) xstream.fromXML(strResp);
            //拼接返回参信息
            String returnCode = response.getINFO().getResFlag();
            if(returnCode=="0"){
                cacpsPayRetuen.setRetCode(returnCode);
                cacpsPayRetuen.setRetMsg(response.getINFO().getErrorMsg());
            }
            else{
                cacpsPayRetuen.setRetMsg(response.getBODY().getRetMsg());
                cacpsPayRetuen.setRetCode(response.getBODY().getRetCode());
                cacpsPayRetuen.setRemark(response.getBODY().getRemark());
                cacpsPayRetuen.setUse(response.getBODY().getUse());
            }
        } catch (Exception e) {
            logger.error("BigError:"+e.getMessage());
        }
        return cacpsPayRetuen;
    }

    /**
     * 请求西安直连支付
     *
     * @param strSendData
     * @return
     */
    private String PayRequest(String strSendData) throws Exception {
        //请求报文 实时代收
        SncaEnvDec sncaEnvDec = new SncaEnvDec();
        PropertiesUtils propertiesUtils = new PropertiesUtils();
        String rootPath = this.getClass().getResource("/").getPath().toString();
        String rootPaths = "/Users/chenzhiheng/CZH/未命名文件夹/直连所需文件/sinopay/sinopay-apiservice-cacpspay/target/test-classes/";
        Properties properties = propertiesUtils.readProperties("/config/cacpsConfig.properties");
        String pfxPath = rootPaths + properties.getProperty("CACPS_PFK_ADDRESS");
        PostMethod postMethod = new PostMethod(properties.getProperty("SERVER_URL"));
        String userName = properties.getProperty("CACPS_LOGIN_USER");
        String corpNo = properties.getProperty("CACPS_CORP_NO");
        String tradeCode = properties.getProperty("CACPS_TRANCODE_S");
        //设置编码
        //发送的报文
        logger.info("发送西安直连报文为：" + strSendData);
        //启动Hissian
        String url = properties.getProperty("CACPS_CS_URL");
        HessianProxyFactory factory = new HessianProxyFactory();
        String strResp = null;
        try {
            uploadFileService = (UploadFileService) factory.create(
                    UploadFileService.class, url);
            String statusCodes = uploadFileService.realTimeSingle(userName,corpNo,tradeCode,strSendData);
            //失败
            if (statusCodes == null) {
                logger.error( "请求失败！");
            } else {
                System.out.println("SUCCESS......");
                //BASE64编码
                BASE64Decoder base64Decoder = new BASE64Decoder();
                byte[] statusCodesByte = base64Decoder.decodeBuffer(statusCodes);
                //读取内容
                strResp = sncaEnvDec.SncaEnvDecStr(pfxPath, pfxPass, new String(statusCodesByte));
                System.out.println("服务器返回:" + "\n" + strResp);
                logger.info("服务器返回:" + strResp);
            }
        }catch (MalformedURLException e) {
            System.out.println("occur exception: " + e);
        }catch (HttpException e) {
            //发生致命的异常，可能是协议不对或者返回的内容有问题
            logger.error("协议有误或者返回的内容有问题!", e);
            e.printStackTrace();
        } catch (IOException e) {
            //发生网络异常
            logger.error("发生网络异常---" + e);
        } catch (Exception e) {
            logger.error("Exception----" + e);
        } finally {
            //释放连接
            postMethod.releaseConnection();
            System.out.println("释放");
            logger.error("释放连接");
        }
        return strResp;
    }



    /**
     * 数据加密
     *
     * @param strData
     * @return
     * @throws Exception
     */
    public String signMsg(String strData) throws Exception {
        //进行String加密
        SncaEnvEnc sncaEnvEnc = new SncaEnvEnc();
        String signMsg = sncaEnvEnc.SncaEnvEncStr(strData);
        //base64编码后得到密文
        BASE64Encoder base64Encoder = new BASE64Encoder();
        signMsg = base64Encoder.encodeBuffer(signMsg.getBytes("GBK"));
        System.out.println("签名值为:" + signMsg);
        logger.info("签名值为:" + signMsg);
        return signMsg;
    }


}
